/* Compiled by XC 1.06 on 28Aug07 */
ylib.namespace('ylib.widget');
ylib.widget.AjaxSuggest = function(elID, url, options) {
    this.elemID = elID ? elID: '';
    this.url = url ? url: '';
    this.options = options ? options: ylib.widget.AjaxSuggest.DefaultOptions();
    this.elem;
    this.elemHid;
    this.suggestions;
    this.contentLoader;
    this.processing = false;
    this.arrOptions = new Array();
    this.lastVal = '';
    this.selectedVal = -1;
    this.hasResults = true;
    this.isTiming = false;
    this.madeRequest = false;
    this.errorHandler = null;
    this.disableHide = false;
    this.tabKeyIndex = '';
    this.SetUp();
};
ylib.widget.AjaxSuggest.DefaultOptions = function() {
    var options = {
        useHiddenValue: false,
        expectValueAndText: false,
        useValueNotText: false,
        suggestionsClassName: 'suggestions',
        suggestionClassName: 'suggestion',
        selectedSuggestionClassName: 'selected-suggestion',
        matchClassName: 'match',
        matchTextWidth: true,
        matchAnywhere: true,
        ignoreCase: true,
        maxSuggestions: 10,
        showMaxMessage: true,
        maxClassName: "suggestion-max",
        maxMessage: "...",
        useTimeout: true,
        timeVisible: 3000,
        method: 'GET',
        params: [],
        showNoMatchMessage: false,
        noMatchClassName: "no-match",
        noMatchMessage: "No matches found",
        disableEnterKey: true
    };
    return options;
};
ylib.widget.AjaxSuggest.prototype = {
    SetUp: function() {
        if (this.elemID == '' || this.url == '' || this.options == '') return;
        var elem,
        parent;
        elem = xGetElementById(this.elemID);
        parent = elem.parentNode;
        if (this.options.useHiddenValue) {
            var newElem = document.createElement("input");
            newElem.id = this.elemID + "SuggestBox";
            parent.replaceChild(newElem, elem);
            xDisplay(elem, 'none');
            parent.appendChild(elem);
            elem = newElem;
        }
        var oThis = this;
        if (!elem) return;
        elem.onkeyup = this.KeyPressed;
        elem.onkeydown = this.KeyIsDown;
        elem.onblur = this.Blurred;
        if (this.options.disableEnterKey && elem.form) {
            elem.form.onsubmit = function() {
                return false;
            };
        }
        this.elem = elem;
        this.suggestions = document.createElement("span");
        this.suggestions.id = this.elemID + "_sugg";
        this.suggestions.className = this.options.suggestionsClassName;
        this.suggestions.style.zIndex = 101;
        this.suggestions.style.position = "absolute";
        this.suggestions.style.left = pageX(this.elem) + "px";//this.elem.offsetLeft
        this.suggestions.style.top = pageY(this.elem)+23 + "px";//(this.elem.offsetTop + this.elem.offsetHeight)
        xDisplay(this.suggestions, "none");
        if (this.options.matchTextWidth) {
            var wdth = this.elem.offsetWidth;
            this.suggestions.style.width = (wdth-2) + "px";
        }
        if (this.options.useTimeout) {
            this.suggestions.onmouseout = this.StartTimeout;
            this.suggestions.onmouseover = this.EraseTimeout;
        } else {
            this.suggestions.onmouseout = null;
            this.suggestions.onmouseover = null;
        }
        this.suggestions.oSuggest = this;
        parent.appendChild(this.suggestions);
        var oThis = this;
        oThis.contentLoader = new ylib.util.ContentLoader(oThis, oThis.url, oThis.AjaxHandler, oThis.errorHandler, oThis.options.method, oThis.options.params);
        elem.oSuggest = this;
    },
    StartTimeout: function() {
        var o = this;
        if (this.oSuggest) {
            o = this.oSuggest;
        }
        o.isTiming = setTimeout("xGetElementById('" + o.elem.id + "').oSuggest.Hide();", o.options.timeVisible);
    },
    EraseTimeout: function() {
        var o = this;
        if (this.oSuggest) {
            o = this.oSuggest;
        }
        clearTimeout(o.isTiming);
        o.isTiming = false;
    },
    TextChanged: function(keyCode) {
        var upArrow = 38;
        var downArrow = 40;
        var rightArrow = 39;
        var leftArrow = 37;
        var tabKey = 9;
        var enterKey = 13;
        if (this.options.useTimeout) {
            if (this.isTiming) this.EraseTimeout();
            this.StartTimeout();
        }
        if (this.elem.value == '') {
            this.arrOptions = new Array();
            this.lastVal = '';
            this.Hide();
            return false;
        }
        switch (keyCode) {
        case(enterKey):
        case(leftArrow):
        case(rightArrow):
        case(tabKey):
            this.GrabHighlighted();
            return false;
        case(upArrow):
            this.MoveHighlighted( - 1);
            return false;
        case(downArrow):
            this.MoveHighlighted(1);
            return false;
        }
        if (this.elem.value.indexOf(this.lastVal) != 0 || ((this.arrOptions.length == 0 || (this.arrOptions.length >= this.options.maxSuggestions)) && this.hasResults) || (this.elem.value.length <= this.lastVal.length) || (this.elem.value.length > 0 && this.lastVal.length == 0)) {
            this.madeRequest = true;
            this.TypeAhead(this.elem.value);
        } else if (!this.madeRequest) {
            this.BuildList(this.elem.value);
        }
        this.lastVal = this.elem.value;
    },
    BuildList: function(targetVal) {
        var matches = this.MakeMatches(targetVal);
        if (matches.length > 0) {
            this.ClearSuggestions();
            for (var i = 0; i < matches.length; i++) {
                if (i == this.options.maxSuggestions) {
                    if (this.options.showMaxMessage) {
                        var sugg = document.createElement("span");
                        sugg.id = this.elemID + "_sug_" + i;
                        sugg.style.width = "100%";
                        xDisplay(sugg, 'block');
                        sugg.className = this.options.maxClassName;
                        sugg.innerHTML = this.options.maxMessage;
                        this.suggestions.appendChild(sugg);
                    }
                    break;
                }
                var sugg = document.createElement("span");
                sugg.id = this.elemID + "_sug_" + i;
                sugg.setAttribute("suggIndex", matches[i].index);
                sugg.setAttribute("index", i);
                sugg.onclick = this.SuggestionClicked;
                sugg.onmouseover = this.SuggestionMouseOver;
                sugg.onmouseout = this.SuggestionMouseOut;
                sugg.style.width = "100%";
                sugg.style.overflow = "hidden";
                sugg.oSuggest = this;
                if (i == 0) {
                    sugg.className = this.options.selectedSuggestionClassName;
                } else {
                    sugg.className = this.options.suggestionClassName;
                }
                xDisplay(sugg, 'block');
                sugg.innerHTML = this.IndicateMatch(matches[i].text, targetVal, i) + " (" + matches[i].loginName + ")";
                sugg.title = matches[i].text +  " (" + matches[i].loginName + ")";
                this.suggestions.appendChild(sugg);
            }
            this.selectedVal = 0;
            this.hasResults = false;
            this.AdjustSuggestionsStyle();
        } else {
            this.selectedVal = -1;
            this.hasResults = true;
            if (this.options.showNoMatchMessage) {
                this.ClearSuggestions();
                var sugg = document.createElement("span");
                sugg.className = this.options.noMatchClassName;
                xDisplay(sugg, 'block');
                sugg.innerHTML = this.options.noMatchMessage;
                this.suggestions.appendChild(sugg);
                this.AdjustSuggestionsStyle();
            } else {
                this.Hide();
            }
        }
    },
    ClearSuggestions: function() {
        if (this.suggestions && this.suggestions.childNodes) {
            for (var i = 0; i < this.suggestions.childNodes.length; i++) {
                this.suggestions.removeChild(this.suggestions.childNodes[i]);
            }
            this.suggestions.innerHTML = '';
        }
    },
    AdjustSuggestionsStyle: function() {
        xDisplay(this.suggestions, "block");
    },
    MakeMatches: function(targetVal) {
        var matchArray = [];
        var reFlags = (this.options.ignoreCase) ? 'i': "";
        var reTxt = (this.options.matchAnywhere) ? "": "^";
        reTxt += targetVal;
        var regEx = new RegExp(reTxt, reFlags);
        for (var i = 0; i < this.arrOptions.length; i++) {
            var match;
            if (this.options.expectValueAndText) {
                match = this.arrOptions[i].text.match(regEx);
            } else {
                match = this.arrOptions[i].match(regEx);
            }
            if (match&&targetVal!=" ") {
                var matchData = {
                    text: "",
                    loginName: "",
                    index: -1
                };
                matchData.index = i;
                if (this.options.expectValueAndText) {
                    matchData.text = this.arrOptions[i].text;
                    matchData.loginName = this.arrOptions[i].loginName;
                } else {
                    matchData.text = this.arrOptions[i];
                }
                matchArray[matchArray.length] = matchData;
            }
        }
        return matchArray;
    },
    IndicateMatch: function(txt, searchTxt, index) {
        var spanStart = "<span class='" + this.options.matchClassName + "'>";
        var spanEnd = "</span>";
        var reFlags = (this.options.ignoreCase) ? 'i': "";
        var reTxt = (this.options.matchAnywhere) ? "": "^";
        reTxt += searchTxt;
        var regEx = new RegExp(reTxt, reFlags);
        var iStart = txt.search(regEx);
        var matchedTxt = txt.substring(iStart, iStart + searchTxt.length);
        return txt.replace(regEx, spanStart + matchedTxt + spanEnd);
    },
    TypeAhead: function(txtVal) {
        this.contentLoader.SendRequest("s=" + encodeURIComponent(txtVal));
    },
    AjaxHandler: function(request) {
        var o = this.component;
        var jsonArray = request.responseText;
        //if (! (jsonArray.substring(0, 1) == "[")) return;
        if (jsonArray) {
            eval("o.arrOptions = " + jsonArray + ";");
            o.BuildList(o.elem.value);
        } else {
            o.arrOptions = [];
        }
        o.madeRequest = false;
    },
    GrabHighlighted: function() {
        if (this.selectedVal >= 0) {
            var selIndex = this.suggestions.childNodes[this.selectedVal].getAttribute("suggIndex");
            this.SetValue(selIndex);
        }
    },
    SetValue: function(index,flag) {
        if (this.options.expectValueAndText) {
            if (this.options.useValueNotText) {
                this.elem.value = this.arrOptions[index].value;
            } else {
                this.elem.value = this.arrOptions[index].text;
            }
        } else {
            this.elem.value = this.arrOptions[index];
        }
        if (this.options.useHiddenValue) {
            var hidElem = xGetElementById(this.elemID);
            if (hidElem) {
                if (this.options.expectValueAndText) {
                    hidElem.value = this.arrOptions[index].value;
                } else {
                    hidElem.value = this.arrOptions[index];
                }
            }
        }
        this.disableHide = false;
        if(!flag)this.Hide();
    },
    MoveHighlighted: function(offset) {
        if ((this.selectedVal >= 0) && (this.suggestions.childNodes)) {
            var newVal = parseInt(this.selectedVal) + parseInt(offset);
            if ((newVal > -1) && (newVal < this.suggestions.childNodes.length) && (newVal < this.options.maxSuggestions)) {
                this.selectedVal = newVal;
            }
            this.MarkSelected();
        }
    },
    MarkSelected: function() {
        if (!this.suggestions.childNodes) return;
        for (var i = 0; i < this.suggestions.childNodes.length; i++) {
            if (i == this.selectedVal) {
                this.suggestions.childNodes[i].className = this.options.selectedSuggestionClassName;
				this.SetValue(i,true)
            } else {
                this.suggestions.childNodes[i].className = this.options.suggestionClassName;
            }
        }
    },
    Blurred: function(e) {
        var keyCode = -1;
        var elem;
        if (window.event) {
            keyCode = event.keyCode;
            elem = event.srcElement;
        } else {
            keyCode = e.which;
            elem = e.target;
        }
        var o = elem.oSuggest;
        if (o.tabKeyIndex != '' && (o.isTiming || !o.options.useTimout)) {
            o.SetValue(o.tabKeyIndex);
        } else {
            o.Hide();
        }
        o.tabKeyIndex = '';
    },
    KeyPressed: function(e) {
        var keyCode = -1;
        var elem = null;
        if (window.event) {
            keyCode = event.keyCode;
            elem = event.srcElement;
        } else {
            keyCode = e.which;
            elem = e.target;
        }
        var o = elem.oSuggest;
        return o.TextChanged(keyCode);
    },
    KeyIsDown: function(e) {
        var keyCode = -1;
        var elem = null;
        if (window.event) {
            keyCode = event.keyCode;
            elem = event.srcElement;
            e = window.event;
        } else {
            keyCode = e.which;
            elem = e.target;
        }
        var o = elem.oSuggest;
        if (keyCode == 13 && o.disableEnterKey) {
            if (e.cancelBubble) {
                e.cancelBubble();
            }
        }
        if (keyCode == 13 || keyCode == 9) {
            var sugg = xGetElementById(o.elemID + "_sug_" + o.selectedVal);
            if (sugg) {
                o.tabKeyIndex = sugg.getAttribute('suggIndex');
            }
        }
        return true;
    },
    SuggestionClicked: function(e) {
        var elem = null;
        if (window.event) {
            elem = event.srcElement;
        } else {
            elem = e.target;
        }
        var o = elem.oSuggest;
        if (!o) {
            elem = elem.parentNode;
            o = elem.oSuggest;
        }
        var index = elem.getAttribute("suggIndex");
        o.SetValue(index);
        return false;
    },
    SuggestionMouseOver: function(e) {
        var elem = null;
        if (window.event) {
            elem = event.srcElement;
        } else {
            elem = e.target;
        }
        var o = elem.oSuggest;
        if (!o) {
            elem = elem.parentNode;
            o = elem.oSuggest;
        }
        o.disableHide = true;
        o.selectedVal = parseInt(elem.getAttribute("index"));
        o.MarkSelected();
    },
    SuggestionMouseOut: function(e) {
        var elem = null;
        if (window.event) {
            elem = event.srcElement;
        } else {
            elem = e.target;
        }
        var o = elem.oSuggest;
        if (!o) {
            elem = elem.parentNode;
            o = elem.oSuggest;
        }
        o.disableHide = false;
    },
    Hide: function() {
        if (!this.disableHide) {
            this.selectedVal = -1;
            xDisplay(this.suggestions, 'none');
            if (this.options.useTimeout) {
                this.EraseTimeout();
            }
        }
    },
    Debug: function(sLog) {
        var el = xGetElementById('log');
        if (el) el.value = sLog + "\n\r" + el.value;
    }
};
